Technical Q&A QA1270
The Data Browser GetDataBrowserUserState API


Q: I am using GetDataBrowserUserState so that I can write my DataBrowser control's user state out to disk. (The user state is information about user customizable settings in the control, such as column widths and orderings.) I tried to call CFDataGetLength on the CFDataRef returned by GetDataBrowserUserState, but this resulted in a crash with "EXC_BAD_ACCESS" on Mac OS X. What am I doing wrong?

A: Unfortunately, the prototype for GetDataBrowserUserState (in Mac OS X 10.2.x and previous) is incorrect; GetDataBrowserUserState does not pass back a CFDataRef, it passes back a CFDictionaryRef.

You can use CFPropertyListyCreateXMLData to convert the CFDictionaryRef into a CFDataRef, thereby making it possible to call CFDataGetLength on the result.

For example:



Listing 1.


CFDataRef state = NULL;

OSStatus err;



ControlRef browser = GetDataBrowserFromWindow(window);

err = GetDataBrowserUserState(browser, &state);



// check that the CFType of state is indeed a CFDictionaryRef

if ((noErr == err) && (CFGetTypeID(state) == CFDictionaryGetTypeID()))

{

  CFDataRef temp = NULL;

  CFIndex index;



  if (state != NULL) // defensive CoreFoundation error checking

  {

    temp = CFPropertyListCreateXMLData(NULL, (CFPropertyListRef)state);

    if (temp != NULL) // defensive CoreFoundation error checking

    {

      index = CFDataGetLength(temp); // length in bytes

      CFRelease(temp); // we created it, we need to release it

    }

  }

}

// The HIToolbox convention is to release references that were

// obtained using api that have "Copy" or "Create" in their names, but

// the DataBrowser api was written before the convention was adopted.

// You must release the item returned by GetDataBrowserUserState.

CFRelease(state);







[Jul 22, 2003]


Developer Documentation | Technical Notes | Development Kits | Sample Code